using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Utils.UGUI.Effect
{
    public class UIGradient : BaseMeshEffect
    {
        public GradientColor gradientColor = GradientColor.Default;

        public override void ModifyMesh(VertexHelper vh)
        {
            if (!IsActive())
                return;
            
            var count = vh.currentVertCount;
            if (count == 0)
                return;

            var vertexList = new List<UIVertex>();
            for (var i = 0; i < count; i++)
            {
                var vertex = new UIVertex();
                vh.PopulateUIVertex(ref vertex, i);
                vertexList.Add(vertex);
            }

            // 获取整体范围
            float minX = float.MaxValue, maxX = float.MinValue;
            float minY = float.MaxValue, maxY = float.MinValue;
            
            foreach (var vertex in vertexList)
            {
                minX = Mathf.Min(minX, vertex.position.x);
                maxX = Mathf.Max(maxX, vertex.position.x);
                minY = Mathf.Min(minY, vertex.position.y);
                maxY = Mathf.Max(maxY, vertex.position.y);
            }

            // 对每个顶点进行颜色插值
            for (int i = 0; i < vertexList.Count; i++)
            {
                var vertex = vertexList[i];
                float normalizedX = Mathf.InverseLerp(minX, maxX, vertex.position.x);
                float normalizedY = Mathf.InverseLerp(minY, maxY, vertex.position.y);

                // 在四个角色之间进行双线性插值
                Color topColor = Color.Lerp(gradientColor.leftUpColor, gradientColor.rightUpColor, normalizedX);
                Color bottomColor = Color.Lerp(gradientColor.leftDownColor, gradientColor.rightDownColor, normalizedX);
                Color finalColor = Color.Lerp(bottomColor, topColor, normalizedY);

                vertex.color *= finalColor;
                vh.SetUIVertex(vertex, i);
            }
        }
        
        public void ForceUpdate()
        {
            if (graphic != null)
            {
                graphic.SetVerticesDirty();
            }
        }
    }
    
    [System.Serializable]
    public struct GradientColor
    {
        public Color leftUpColor;
        public Color rightUpColor ;
        public Color leftDownColor ;
        public Color rightDownColor;
        
        public static GradientColor Default => new GradientColor
        {
            leftUpColor = Color.white,
            rightUpColor = Color.white,
            leftDownColor = Color.white,
            rightDownColor = Color.white
        };
        
        public static GradientColor Lerp(GradientColor a, GradientColor b, float t)
        {
            return new GradientColor
            {
                leftUpColor = Color.Lerp(a.leftUpColor, b.leftUpColor, t),
                rightUpColor = Color.Lerp(a.rightUpColor, b.rightUpColor, t),
                leftDownColor = Color.Lerp(a.leftDownColor, b.leftDownColor, t),
                rightDownColor = Color.Lerp(a.rightDownColor, b.rightDownColor, t)
            };
        }
        
        public void Lerp(GradientColor target, float t)
        {
            leftUpColor = Color.Lerp(leftUpColor, target.leftUpColor, t);
            rightUpColor = Color.Lerp(rightUpColor, target.rightUpColor, t);
            leftDownColor = Color.Lerp(leftDownColor, target.leftDownColor, t);
            rightDownColor = Color.Lerp(rightDownColor, target.rightDownColor, t);
        }
    }
}